#include <muduo/base/Logging.h>
#include <muduo/base/ThreadLocalSingleton.h>
#include "BankSession.h"
#include "TransactionManager.h"
#include "Singleton.h"

using namespace muduo;

static void SendEmpty(const char *,size_t)
{
}

typedef	ThreadLocalSingleton<TransactionManager> LocalTransactionManager;

BankSession::BankSession()
{
	assert(LocalTransactionManager::pointer() == NULL);
	LocalTransactionManager::instance();
	assert(LocalTransactionManager::pointer() != NULL);
	requestPack_= (RequestPack*)buffer_;
	sfp_ = boost::bind(&SendEmpty,_1,_2);
}

BankSession::~BankSession()
{
}

void BankSession::Process(const char *buf,size_t len)
{
	memset(buffer_,0,sizeof(buffer_));
	memcpy(buffer_,buf,len);
	Recv();
	DoAction();
}

void BankSession::Send(const char* buf, size_t len)
{
	sfp_(buf,len);
}

void BankSession::Recv()
{
	int ret;
	uint16_t cmd = Endian::NetworkToHost16(requestPack_->head.cmd);
	uint16_t len = Endian::NetworkToHost16(requestPack_->head.len);
	// 计算hash
	unsigned char hash[16];
	MD5 md5;
	md5.MD5Make(hash, (unsigned char const *)buffer_, sizeof(RequestHead)+len-8);
	for (int i=0; i<8; ++i)
	{
		hash[i] = hash[i] ^ hash[i+8];
		hash[i] = hash[i] ^ ((cmd >> (i%2)) & 0xff);
	}

	if(memcmp(hash, buffer_+sizeof(RequestHead)+len-8, 8)) {
		LOG_ERROR << "错误的数据包";
	}
	requestPack_->head.cmd = cmd;
	requestPack_->head.len = len;
}

void BankSession::DoAction()
{
	LocalTransactionManager::instance().DoAction(*this);
}
